<!--
【位置管理页面】
此页面用于展示和管理系统中的位置层级结构，支持树形视图显示。
主要功能：
1. 显示位置树形结构，支持展开/折叠
2. 切换是否显示关联的资产
3. 支持全部展开/折叠操作
4. 树状态持久化（URL参数保存）
-->

<script setup lang="ts">
  // 【国际化】使用vue-i18n进行多语言支持
  import { useI18n } from "vue-i18n";
  
  // 【树状态管理】用于管理位置树的展开/折叠状态
  import { useTreeState } from "~~/components/Location/Tree/tree-state";
  
  // 【图标组件】引入各种图标组件用于UI显示
  import MdiCollapseAllOutline from "~icons/mdi/collapse-all-outline";
  import MdiExpandAllOutline from "~icons/mdi/expand-all-outline";
  import MdiPackageVariant from "~icons/mdi/package-variant";
  import MdiMapMarker from "~icons/mdi/map-marker";
  
  // 【UI组件】引入按钮、工具提示、开关、标签等组件
  import { ButtonGroup, Button } from "@/components/ui/button";
  import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
  import { Switch } from "@/components/ui/switch";
  import { Label } from "@/components/ui/label";
  
  // 【类型定义】引入树形结构的数据类型
  import type { TreeItem } from "~/lib/api/types/data-contracts";

  // 【国际化】获取翻译函数
  const { t } = useI18n();

  // 【页面元数据】设置页面访问权限和标题
  definePageMeta({
    middleware: ["auth"], // 需要认证才能访问
  });

  useHead({
    title: "HomeBox | " + t("menu.locations"), // 设置浏览器标题
  });

  // 【API客户端】获取用户API实例
  const api = useUserApi();

  // 【状态管理】使用全局UI store的showItemsInLocations状态
  const globalUIStore = useGlobalUIStore();
  
  // 计算属性，双向绑定到globalUIStore的showItemsInLocations
  const showItems = computed({
    get: () => {
      return globalUIStore.showItemsInLocations;
    },
    set: (value: boolean) => {
      globalUIStore.setShowItemsInLocations(value);
    }
  });
  
  // 【数据存储】分别存储包含资产和不包含资产的位置树数据
  const treeWithItems = ref<TreeItem[]>([]);      // 包含资产的位置树
  const treeWithoutItems = ref<TreeItem[]>([]);   // 不包含资产的位置树
  
  /**
   * 【数据加载】获取包含资产的位置树数据
   * 从后端API获取包含关联资产的位置层级结构
   */
  async function loadTreeWithItems() {
    const { data, error } = await api.locations.getTree({
      withItems: true, // 包含资产数据
    });
    
    treeWithItems.value = error ? [] : data || [];
  }

  /**
   * 【数据加载】获取不包含资产的位置树数据
   * 从后端API获取纯位置层级结构，不包含资产信息
   */
  async function loadTreeWithoutItems() {
    const { data, error } = await api.locations.getTree({
      withItems: false, // 不包含资产数据
    });
    
    treeWithoutItems.value = error ? [] : data || [];
  }

  /**
   * 【计算属性】根据开关状态返回对应的位置树数据
   * showItems为true时返回包含资产的数据，否则返回不包含资产的数据
   */
  const tree = computed(() => {
    return showItems.value ? treeWithItems.value : treeWithoutItems.value;
  });

  /**
   * 【监听器】监听showItems变化，自动切换数据源
   * 当用户切换"显示资产"开关时，自动加载对应的数据
   */
  watch(showItems, async (newValue) => {
    if (newValue) {
      await loadTreeWithItems(); // 加载包含资产的数据
    } else {
      await loadTreeWithoutItems(); // 加载不包含资产的数据
    }
  }, { immediate: true }); // 设置为true，确保组件挂载时立即执行



  // 【树状态管理】定义树的唯一标识符
  const locationTreeId = "locationTree";
  
  // 【状态管理】使用自定义hook管理树状态
  const treeState = useTreeState(locationTreeId);
  const route = useRouter();

  /**
   * 【URL状态恢复】从URL查询参数恢复树状态
   * 当页面刷新或分享链接时，可以从URL中恢复之前的展开状态
   */
  onMounted(() => {
    const query = route.currentRoute.value.query;
    if (query && query[locationTreeId]) {
      const data = JSON.parse(query[locationTreeId] as string);
      for (const key in data) {
        treeState.value[key] = data[key];
      }
    }
  });

  /**
   * 【URL状态保存】将树状态保存到URL查询参数
   * 当用户展开/折叠树节点时，自动更新URL以便状态持久化
   */
  watch(
    treeState,
    () => {
      route.replace({ query: { [locationTreeId]: JSON.stringify(treeState.value) } });
    },
    { deep: true } // 深度监听对象变化
  );

  /**
   * 【树操作】关闭所有展开的节点
   * 将所有节点的展开状态设置为false
   */
  function closeAll() {
    for (const key in treeState.value) {
      treeState.value[key] = false;
    }
  }

  /**
   * 【树操作】递归展开所有子节点
   * 遍历整个树结构，将所有有子节点的父节点设置为展开状态
   */
  function openItemChildren(items: TreeItem[]) {
    for (const item of items) {
      if (item.children.length > 0) {
        // 使用节点ID的前8位作为状态键，避免特殊字符
        treeState.value[item.id.replace(/-/g, "").substring(0, 8)] = true;
        openItemChildren(item.children); // 递归处理子节点
      }
    }
  }

  /**
   * 【树操作】展开整个树
   * 调用openItemChildren展开当前显示的所有位置节点
   */
  function openAll() {
    if (!tree.value) return; // 数据未加载完成时直接返回
    openItemChildren(tree.value);
  }


</script>

<template>
  <!-- 【页面容器】使用基础容器组件提供页面布局 -->
  <BaseContainer>
    <!-- 【页面头部】包含标题和控制区域 -->
    <div class="mb-2 flex justify-between">
      <!-- 【页面标题】显示当前页面名称 -->
      <BaseSectionHeader> {{ $t("menu.locations") }} </BaseSectionHeader>
      
      <!-- 【控制区域】包含开关和按钮组 -->
      <div class="flex items-center gap-4">
        <!-- 【树操作按钮组】提供展开/折叠全部节点的功能 -->
        <TooltipProvider :delay-duration="0">
          <ButtonGroup>
            <!-- 【展开全部按钮】点击后展开所有位置节点 -->
            <Tooltip>
              <TooltipTrigger>
                <Button size="icon" variant="outline" data-pos="start" @click="openAll">
                  <MdiExpandAllOutline />
                </Button>
              </TooltipTrigger>
              <TooltipContent>
                <p>{{ $t("locations.expand_tree") }}</p>
              </TooltipContent>
            </Tooltip>
            
            <!-- 【折叠全部按钮】点击后折叠所有位置节点 -->
            <Tooltip>
              <TooltipTrigger>
                <Button size="icon" variant="outline" data-pos="end" @click="closeAll">
                  <MdiCollapseAllOutline />
                </Button>
              </TooltipTrigger>
              <TooltipContent>
                <p>{{ $t("locations.collapse_tree") }}</p>
              </TooltipContent>
            </Tooltip>
          </ButtonGroup>
        </TooltipProvider>

       
      </div>
    </div>
    
    <!-- 【主要内容区域】显示位置树 -->
    <BaseCard>
      <div class="p-2">
        <!-- 【位置树组件】根据当前数据源渲染树形结构 -->
        <LocationTreeRoot 
          v-if="tree"
          :locs="tree"
          :tree-id="locationTreeId"
        />
      </div>
    </BaseCard>
  </BaseContainer>
</template>

